package com.yy.jhl.util;

import android.content.Context;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.yy.common.commonutils.LogUtils;
import com.yy.common.commonutils.NetWorkUtils;
import com.yy.common.commonutils.StringUtil;
import com.yy.common.commonutils.ToastUitl;
import com.yy.jhl.bean.LocationInfo;
import com.yy.jhl.ui.manager.activity.MainWithCodeActivity;

/**
 * Created by Ellis.Li on 2017/6/12.
 */

public class LocationUtil {
    static LocationUtil instance;
    static Context mContext;
    // 定位相关
    LocationClient mLocClient;
    private boolean isLocation = false;
    private  BDLocationCallBack bdLocationCallBack;
    public static LocationUtil getInstance(Context cxt){
        mContext = cxt;
        if (instance == null){
            synchronized (LocationUtil.class) {
                if (instance == null){
                    instance = new LocationUtil();
                }
            }
        }
        return instance;
    }

    public LocationUtil() {
        initLocation();
    }

    public void  initLocation() {
        if (mLocClient == null){
//            mLocClient = new LocationClient(this);
//            mLocClient.registerLocationListener(new MainWithCodeActivity.MyLocationListenner());
//            LocationClientOption option = new LocationClientOption();
//            option.setOpenGps(true); // 打开gps
//            option.setCoorType("bd09ll"); // 设置坐标类型
//            option.setScanSpan(1000);
            mLocClient = new LocationClient(mContext);
            LocationClientOption mOption = new LocationClientOption();
            mOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
            mOption.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系，如果配合百度地图使用，建议设置为bd09ll;
            mOption.setScanSpan(1000);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
            mOption.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
            mOption.setIsNeedLocationDescribe(true);//可选，设置是否需要地址描述
            mOption.setNeedDeviceDirect(false);//可选，设置是否需要设备方向结果
            mOption.setLocationNotify(false);//可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
            mOption.setIgnoreKillProcess(true);//可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
            mOption.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
            mOption.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
            mOption.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
            mLocClient.setLocOption(mOption);
            mLocClient.registerLocationListener(bdLocationListener);
        }
        if (mLocClient.isStarted()){
            mLocClient.requestLocation();
        }else {
            mLocClient.start();
        }
    }

    /**
     * 位置监听
     */
    private BDLocationListener bdLocationListener = new BDLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (!isLocation){
                isLocation = true;
                logLocation(bdLocation);
                StringBuffer address = new StringBuffer();
                if (!NetWorkUtils.isNetConnected(mContext) || StringUtil.isEmpty(bdLocation.getProvince())){
                    ToastUitl.showShort("定位失败，请检查您的网络");
                    bdLocationCallBack.getBDLocation(new LocationInfo());
                    return;

                }
                if (!StringUtil.isEmpty(bdLocation.getAddrStr()) && bdLocation.getAddrStr().length() > 2){
                    address.append(bdLocation.getAddrStr().substring(2));
                }
                if (bdLocation.getPoiList() != null && !bdLocation.getPoiList().isEmpty()) {
                    address.append(((Poi)bdLocation.getPoiList().get(0)).getName());
                }
                LocationInfo locationInfo = new LocationInfo(bdLocation.getProvince(),bdLocation.getCity()+bdLocation.getDistrict()+bdLocation.getStreet()+bdLocation.getStreetNumber(),bdLocation.getDistrict(),
                        address.toString(),String.valueOf(bdLocation.getLongitude()),String.valueOf(bdLocation.getLatitude()));
                bdLocationCallBack.getBDLocation(locationInfo);
            }
        }
    } ;
    /**
     * 获取位置信息
     * @param locationCallBack
     */
    public void getBaiDuLocation(final BDLocationCallBack locationCallBack){
        isLocation = false;
        if (bdLocationCallBack != null){
            bdLocationCallBack = null;
        }
        bdLocationCallBack = locationCallBack;
        initLocation();
    }

    /**
     * 销毁定位信息
     */
    public void clearLocation(){
        // 退出时销毁定位
        if (mLocClient == null)return;
        mLocClient.unRegisterLocationListener(bdLocationListener);
        mLocClient.stop();
        mLocClient = null;
    }
    public interface BDLocationCallBack{
        public void getBDLocation(LocationInfo locationInfo);
    }
    private void logLocation(BDLocation location){
            if (location == null)return;
            StringBuffer sb = new StringBuffer(256);
            sb.append("time : ");
            /**
             * 时间也可以使用systemClock.elapsedRealtime()方法 获取的是自从开机以来，每次回调的时间；
             * location.getTime() 是指服务端出本次结果的时间，如果位置不发生变化，则时间不变
             */
            sb.append(location.getTime());
            sb.append("\nlocType : ");// 定位类型
            sb.append(location.getLocType());
            sb.append("\nlocType description : ");// *****对应的定位类型说明*****
            sb.append("\nlatitude : ");// 纬度
            sb.append(location.getLatitude());
            sb.append("\nlontitude : ");// 经度
            sb.append(location.getLongitude());
            sb.append("\nradius : ");// 半径
            sb.append(location.getRadius());
            sb.append("\nCountryCode : ");// 国家码
            sb.append(location.getCountryCode());
            sb.append("\nCountry : ");// 国家名称
            sb.append(location.getCountry());
            sb.append("\ncitycode : ");// 城市编码
            sb.append(location.getCityCode());
            sb.append("\ncity : ");// 城市
            sb.append(location.getCity());
            sb.append("\nDistrict : ");// 区
            sb.append(location.getDistrict());
            sb.append("\nStreet : ");// 街道
            sb.append(location.getStreet());
            sb.append("\naddr : ");// 地址信息
            sb.append(location.getAddrStr());
            sb.append("\nUserIndoorState: ");// *****返回用户室内外判断结果*****
            sb.append("\nDirection(not all devices have value): ");
            sb.append(location.getDirection());// 方向
            sb.append("\nlocationdescribe: ");
            sb.append(location.getLocationDescribe());// 位置语义化信息
            sb.append("\nPoi: ");// POI信息
            if (location.getPoiList() != null && !location.getPoiList().isEmpty()) {
                for (int i = 0; i < location.getPoiList().size(); i++) {
                    Poi poi = (Poi) location.getPoiList().get(i);
                    sb.append(poi.getName() + ";");
                }
            }
            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位结果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 速度 单位：km/h
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());// 卫星数目
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 海拔高度 单位：米
                sb.append("\ngps status : ");
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 网络定位结果
                // 运营商信息
                if (location.hasAltitude()) {// *****如果有海拔高度*****
                    sb.append("\nheight : ");
                    sb.append(location.getAltitude());// 单位：米
                }
                sb.append("\noperationers : ");// 运营商信息
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("网络定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 离线定位结果
                sb.append("\ndescribe : ");
                sb.append("离线定位成功，离线定位结果也是有效的");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服务端网络定位失败，可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com，会有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("网络不同导致定位失败，请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("无法获取有效定位依据导致定位失败，一般是由于手机的原因，处于飞行模式下一般会造成这种结果，可以试着重启手机");
            }
          LogUtils.loge(sb.toString());
    }
}
